package com.xuxk.project.library.util;


import org.apache.commons.lang.StringUtils;
import org.springframework.web.util.UrlPathHelper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;

public class RequestUtils {

	/**
	 * 获取QueryString的参数，并使用URLDecoder以UTF8格式转码。如果请求是以post方法提交的，
	 * 那么将通过HttpServletRequest#getParameter获取。
	 * 
	 * @param request
	 *            web请求
	 * @param name
	 *            参数名称
	 * @return
	 */
	public static String getQueryParam(HttpServletRequest request, String name) {
		if (StringUtils.isBlank(name)) {
			return null;
		}
		if (request.getMethod().equalsIgnoreCase("POST")) {
			return request.getParameter(name);
		}
		String s = request.getQueryString();
		if (StringUtils.isBlank(s)) {
			return null;
		}
		try {
			s = URLDecoder.decode(s, "UTF-8");
		} catch (UnsupportedEncodingException e) {
		}
		String[] values = parseQueryString(s).get(name);
		if (values != null && values.length > 0) {
			return values[values.length - 1];
		} else {
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static Map<String, Object> getQueryParams(HttpServletRequest request) {
		Map<String, String[]> map;
		if (request.getMethod().equalsIgnoreCase("POST")) {
			map = request.getParameterMap();
		} else {
			String s = request.getQueryString();
			if (StringUtils.isBlank(s)) {
				return new HashMap<String, Object>();
			}
			try {
				s = URLDecoder.decode(s, "UTF-8");
			} catch (UnsupportedEncodingException e) {
			}
			map = parseQueryString(s);
		}

		Map<String, Object> params = new HashMap<String, Object>(map.size());
		int len;
		for (Map.Entry<String, String[]> entry : map.entrySet()) {
			len = entry.getValue().length;
			if (len == 1) {
				params.put(entry.getKey(), entry.getValue()[0]);
			} else if (len > 1) {
				params.put(entry.getKey(), entry.getValue());
			}
		}
		return params;
	}
	/**
	 * 请求参数转成map
	 * @param queryParams
	 * @return
	 */
	public static Map<String, Object> strToMap(String queryParams){
		Map<String, String[]> map ;
		Map<String, Object> params = null ;
		try {
			map = parseQueryString(queryParams);
			params = new HashMap<String, Object>(map.size());
			int len;
			for (Map.Entry<String, String[]> entry : map.entrySet()) {
				len = entry.getValue().length;
				if (len == 1) {
					params.put(entry.getKey(), entry.getValue()[0]);
				} else if (len > 1) {
					params.put(entry.getKey(), entry.getValue());
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace() ;
		}
		return params ;
		
	}
	
	public static Map<String, String[]> parseQueryString(String s) {
		String valArray[] = null;
		if (s == null) {
			throw new IllegalArgumentException();
		}
		Map<String, String[]> ht = new HashMap<String, String[]>();
		StringTokenizer st = new StringTokenizer(s, "&");
		while (st.hasMoreTokens()) {
			String pair = (String) st.nextToken();
			int pos = pair.indexOf('=');
			if (pos == -1) {
				continue;
			}
			String key = pair.substring(0, pos);
			String val = pair.substring(pos + 1, pair.length());
			if (ht.containsKey(key)) {
				String oldVals[] = (String[]) ht.get(key);
				valArray = new String[oldVals.length + 1];
				for (int i = 0; i < oldVals.length; i++) {
					valArray[i] = oldVals[i];
				}
				valArray[oldVals.length] = val;
			} else {
				valArray = new String[1];
				valArray[0] = val;
			}
			ht.put(key, valArray);
		}
		return ht;
	}
	
	
	public static Map<String, Object> parseRequestQueryString(String s) {
		if (StringUtils.isBlank(s)) {
			throw new IllegalArgumentException();
		}
		Map<String, Object> ht = new HashMap<String, Object>();
		StringTokenizer st = new StringTokenizer(s, "&");
		while (st.hasMoreTokens()) {
			String pair = (String) st.nextToken();
			int pos = pair.indexOf('=');
			if (pos == -1) {
				continue;
			}
			String key = pair.substring(0, pos);
			String val = pair.substring(pos + 1, pair.length());
			ht.put(key, val);
		}
		return ht;
	}

	@SuppressWarnings("unchecked")
	public static Map<String, String> getRequestMap(HttpServletRequest request,
                                                    String prefix) {
		Map<String, String> map = new HashMap<String, String>();
		Enumeration<String> names = request.getParameterNames();
		String name;
		while (names.hasMoreElements()) {
			name = names.nextElement();
			if (name.startsWith(prefix)) {
				request.getParameterValues(name);
				map.put(name.substring(prefix.length()), StringUtils.join(
						request.getParameterValues(name), ','));
			}
		}
		return map;
	}

	
	/**
	 * 获取访问者IP
	 * @param request
	 * @return
	 */
	public static String getRealIp(HttpServletRequest request) {
		final String x_real_ip = request.getHeader("HTTP_X_REAL_IP");
		if (StringUtils.isNotEmpty(x_real_ip)) {
			return x_real_ip;
		}
		final String X_Forwarded_For = request.getHeader("X-Forwarded-For");
		if (StringUtils.isNotEmpty(X_Forwarded_For)) {
			return X_Forwarded_For;
		}
		return request.getRemoteAddr();
	}
	/**
	 * 获取访问者IP
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		final String cdnIp = request.getHeader("Cdn-Src-Ip");
		if (StringUtils.isNotEmpty(cdnIp)) {
			return cdnIp;
		}
		final String forwardIp = request.getHeader("HTTP_X_FORWARDED_FOR");
		if (StringUtils.isNotEmpty(forwardIp)) {
			return forwardIp;
		}
		final String realIp = request.getHeader("HTTP_X_REAL_IP");
		if (StringUtils.isNotEmpty(realIp)) {
			return realIp;
		}
		final String wlProxyClientIp =  request.getHeader("WL-Proxy-Client-IP");
		if (StringUtils.isNotEmpty(wlProxyClientIp)) {
			return wlProxyClientIp;
		}
		
		final String proxyClientIp =  request.getHeader("Proxy-Client-IP");
		if (StringUtils.isNotEmpty(proxyClientIp)) {
			return proxyClientIp;
		}
		
		return request.getRemoteAddr();
	}

	/**
	 * 获得当的访问路径
	 * 
	 * HttpServletRequest.getRequestURL+"?"+HttpServletRequest.getQueryString
	 * 
	 * @param request
	 * @return
	 */
	public static String getLocation(HttpServletRequest request) {
		UrlPathHelper helper = new UrlPathHelper();
		StringBuffer buff = request.getRequestURL();
		String uri = request.getRequestURI();
		String origUri = helper.getOriginatingRequestUri(request);
		buff.replace(buff.length() - uri.length(), buff.length(), origUri);
		String queryString = helper.getOriginatingQueryString(request);
		if (queryString != null) {
			buff.append("?").append(queryString);
		}
		return buff.toString();
	}
	public static String mapToStr(HashMap params){
		StringBuffer buff = new StringBuffer();
		Set set = params.keySet();
		Iterator it = set.iterator();
		while(it.hasNext()){
			String key = (String) it.next();
			String value = (String) params.get(key);
			buff.append("&").append(key).append("=").append(value);
		}
		return buff.toString().replaceFirst("&", "");
	}

	public static void toForword(HttpServletResponse response, String toURL){
		try {
			response.sendRedirect(toURL);
			PrintWriter out = response.getWriter();
			out.flush();
			out.close();
		} catch (IOException e) {
			;
		}
	}
	
	public static String getParameterNullSafe(HttpServletRequest request,
                                              String paramName) {
		String ret = request.getParameter(paramName);
		if (ret == null) {
			ret = "";
		}
		return ret;
	}
	/**
	 * 从请求地址中获取最后斜杠“/”后面的请求地址内容
	 * @param requestURI
	 * @return
	 */
	public static String getLastRequestURI(String requestURI) {
	
		String requstUrlContent = requestURI ;
		try {
			if(StringUtils.isNotBlank(requestURI)
					&& requestURI.indexOf("/")!=-1){
				String[] requestURIs = requestURI.split("[/]");
				requstUrlContent = requestURIs[requestURIs.length-1];
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return requstUrlContent ;
		
	}

	/**
	 * 获取request中的header
	 * @param request
	 * @return
	 */
	public static Map<String, String> getHeadersInfo(HttpServletRequest request) {
		Map<String, String> map = new HashMap<>();
		Enumeration headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String key = (String) headerNames.nextElement();
			String value = request.getHeader(key);
			map.put(key, value);
		}

		return map;
	}


}
